/**
 * Copyright(C)版权所有 中国电子科技集团公司第三十二研究所
 * @Title: VfileMenuController数据管理文件目录视图操作接口
 * @author: xiao
 * @version: 1.0
 * @date: 2020/10/14
 * 备注:无
 */
package com.cetc32.dh.controller.rest;

import com.cetc32.dh.common.response.PageDataResult;
import com.cetc32.dh.common.response.ResponseResult;
import com.cetc32.dh.entity.Options;
import com.cetc32.dh.entity.VfileMenu;
import com.cetc32.dh.service.DataFileService;
import com.cetc32.dh.service.OptionsService;
import com.cetc32.dh.service.VfileMenuService;
import com.cetc32.dh.utils.FileUtil;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 数据管理文件目录视图类
 * @author: xiao
 * @version: 1.0
 * @date: 2020/10/14
 * 备注:无
 */
@Api(value = "Data File Info")
@Slf4j
@RestController
@RequestMapping("/rest/file/")
public class VfileMenuController {

    @Autowired
    public VfileMenuService vfileMenuService;
    @Autowired
    public OptionsService optionsService;
    @Autowired
    public DataFileService dataFileService;

    /**
     * 根据目录节点id和文件安全性查询文件
     *
     * @param pageNum
     * @param pageSize
     * @param fileSecurity
     * @return pdr
     * 备注:无
     */
    @PostMapping("/queryByFileSecurityAndMenuId")
    public PageDataResult queryByFileSecurityAndMenuId(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize, Long menuId, String fileSecurity) {
        PageDataResult pdr = new PageDataResult();
        if (pageNum == null || pageNum == 0) {
            pageNum = 1;
        }
        if (pageSize == null || pageSize == 0)
            pageSize = 10;

        pdr.setTotals(vfileMenuService.queryByFileSecurityAndMenuId(menuId, fileSecurity).size());
        PageHelper.startPage(pageNum, pageSize);
        pdr.setList(vfileMenuService.queryByFileSecurityAndMenuId(menuId, fileSecurity));
        return pdr;
    }

    /**
     * 查询目录节点id下的文件
     *
     * @param pageNum
     * @param pageSize
     * @param menuId
     * @return pdr
     * 备注:无
     */
    @PostMapping("/queryFilesByMenuId")
    public PageDataResult queryFilesByMenuId(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize, Long menuId) {
        PageDataResult pdr = new PageDataResult();
        if (pageNum == null || pageNum == 0) {
            pageNum = 1;
        }
        if (pageSize == null || pageSize == 0)
            pageSize = 10;

        pdr.setTotals(vfileMenuService.queryFilesByMenuId(menuId).size());
        PageHelper.startPage(pageNum, pageSize);
        pdr.setList(vfileMenuService.queryFilesByMenuId(menuId));
        return pdr;

    }

    /**
     * 根据目录节点id和文件时间查询文件
     *
     * @param pageNum
     * @param pageSize
     * @param menuId
     * @param time
     * @return pdr
     * 备注:无
     */
    @PostMapping("/queryFilesByTime")
    public PageDataResult queryFilesByTime(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize, Long menuId, Date time) {
        PageDataResult pdr = new PageDataResult();
        if (pageNum == null || pageNum == 0) {
            pageNum = 1;
        }
        if (pageSize == null || pageSize == 0)
            pageSize = 10;

        pdr.setTotals(vfileMenuService.queryFilesByTime(menuId, time).size());
        PageHelper.startPage(pageNum, pageSize);
        pdr.setList(vfileMenuService.queryFilesByTime(menuId, time));
        return pdr;

    }

    /**
     * 根据目录节点id和文件区域查询文件
     *
     * @param pageNum
     * @param pageSize
     * @param menuId
     * @param region
     * @return pdr
     * 备注:无
     */
    @PostMapping("/queryFilesByRegion")
    public PageDataResult queryFilesByRegion(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize, Long menuId, String region) {
        PageDataResult pdr = new PageDataResult();
        if (pageNum == null || pageNum == 0) {
            pageNum = 1;
        }
        if (pageSize == null || pageSize == 0)
            pageSize = 10;

        pdr.setTotals(vfileMenuService.queryFilesByRegion(menuId, region).size());
        PageHelper.startPage(pageNum, pageSize);
        pdr.setList(vfileMenuService.queryFilesByRegion(menuId, region));
        return pdr;

    }

    /**
     * 根据目录节点id、文件名字、文件年份、文件区域、文件类型和文件安全性查询文件
     *
     * @param pageNum
     * @param pageSize
     * @param fileName
     * @param fileYear
     * @param region
     * @param fileType
     * @param fileSecurity
     * @return pdr
     * 备注:无
     */
    @PostMapping("/queryFilesByChoose")
    public PageDataResult queryFilesByChoose(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize, String fileName, Integer fileYear, String region, String fileType, String fileSecurity) {
        PageDataResult pdr = new PageDataResult();
        if (pageNum == null || pageNum == 0) {
            pageNum = 1;
        }
        if (pageSize == null || pageSize == 0)
            pageSize = 10;

        pdr.setTotals(vfileMenuService.queryFilesByChoose(fileName, fileYear, region, fileType, fileSecurity).size());
        PageHelper.startPage(pageNum, pageSize);
        pdr.setList(vfileMenuService.queryFilesByChoose(fileName, fileYear, region, fileType, fileSecurity));
        return pdr;

    }

    /**
     * 根据目录节点id和文件视图对象查询文件
     *
     * @param vfileMenu
     * @return pdr
     * 备注:无
     */
    @ApiOperation(value = "查询所有数据接口", notes = "至少传入page，和current两个参数")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", paramType = "body", dataType = "Integer", required = true, defaultValue = "1"),
            @ApiImplicitParam(name = "results", value = "每页数据条数", paramType = "body", dataType = "Integer", required = true, defaultValue = "10"),
            @ApiImplicitParam(name = "fileName", value = "文件名称", paramType = "body", defaultValue = ""),
            @ApiImplicitParam(name = "fileYear", value = "文件年份", paramType = "body", dataType = "Integer", defaultValue = ""),
            @ApiImplicitParam(name = "fileType", value = "文件类型", paramType = "body", defaultValue = ""),
            @ApiImplicitParam(name = "fileSecurity", value = "文件安全等级", paramType = "body", dataType = "Integer", defaultValue = ""),
            @ApiImplicitParam(name = "region", value = "文件区域", paramType = "body", defaultValue = ""),
            @ApiImplicitParam(name = "menuId", value = "目录节点", paramType = "body", dataType = "Integer", defaultValue = "")
    })
    @PostMapping("/find")
    public PageDataResult queryFilesByObj(@RequestBody VfileMenu vfileMenu) {
        System.out.println(vfileMenu.getMenuId());
        Integer page = vfileMenu.getPage();
        Integer results = vfileMenu.getResults();

        if (page == null || page <= 0) {
            page = 1;
        }
        if (results == null || results <= 0)
            results = 10;

        int offset = (page - 1) * results;

        return new PageDataResult(vfileMenuService.countFilesByObj(vfileMenu),
                vfileMenuService.queryFilesByObj(offset, results, vfileMenu),
                offset);

    }


    /**
     * 查询options中所有的不同年份
     *
     * @return List<Integer>
     */
    @ApiOperation(value = "查询所有年份", notes = "不需要传参数")
    @PostMapping("/AllYear")
    //@RequestMapping(value="/AllYear",method = RequestMethod.POST)
    public ResponseResult distinctAllYear() {
        List<Options> optionsList = optionsService.selectByCategory("file_year");
        List<Integer> yearList = new ArrayList<Integer>();
        for(int i=0;i<optionsList.size();i++){
            yearList.add(Integer.parseInt(optionsList.get(i).getValueName()));
        }
        Collections.sort(yearList);
        Collections.reverse(yearList);
        List<String> resultList = new ArrayList<String>();
        resultList.add("全部年份");
        for (int i = 0; i < yearList.size(); i++) {
            resultList.add(yearList.get(i).toString());
        }

        return ResponseResult.success(resultList);
    }


    /**
     * 查询options中所有的不同区域
     *
     * @return List<String>
     */
    @ApiOperation(value = "查询所有区域", notes = "不需要传参数")
    @PostMapping("/AllRegion")
    public ResponseResult distinctAllRegion() {
        List<Options> optionsList = optionsService.selectByCategory("region");
        List<String> regionList = new ArrayList<String>();
        for(int i=0;i<optionsList.size();i++){
            regionList.add(optionsList.get(i).getValueName());
        }

        List<String> resultList = new ArrayList<String>();
        resultList.add("全部区域");
        for (int i = 0; i < regionList.size(); i++) {
            resultList.add(regionList.get(i).toString());
        }

        return ResponseResult.success(resultList);
    }



    /**
     * 查询数据库中所有的不同文件类型
     *
     * @return List<String>
     */
    @ApiOperation(value = "查询文件类型", notes = "不需要传参数")
    @PostMapping("/AllFtype")
    public ResponseResult optFType() {
        List<Options> optionsList = optionsService.selectByCategory("file_type");
        List<Map> hashMapList = new ArrayList<>();
        Map<String, String> hashmap = new HashMap<>();
        hashmap.put("value", "全部类型");
        hashmap.put("label", "全部类型");
        hashMapList.add(hashmap);
        for (int i = 0; i < optionsList.size(); i++) {
            Map<String, String> hashmap2 = new HashMap<>();
            hashmap2.put("value", optionsList.get(i).getValue());
            hashmap2.put("label", optionsList.get(i).getValueName());
            hashMapList.add(hashmap2);
        }
        return ResponseResult.success(hashMapList);
    }


    /**
     * 下载文件文件，文件夹
     *
     * @return String
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileIds", value = "文件id", paramType = "body", dataType = "List"),
    })
    @GetMapping("/downloadMulFile")
    public String downloadMulFile(String[] fileIds, HttpServletResponse response) {

        if (fileIds.length == 1) {
            Long fileId = Long.parseLong(fileIds[0]);
            String fileName = dataFileService.queryById(fileId).getFileName();
            String filePath = dataFileService.queryById(fileId).getFilePath() + File.separator + dataFileService.queryById(fileId).getFileName();
            if (!FileUtil.isDirectory(filePath)) {
                FileUtil.downloadFile(response, fileName, filePath);
            }
        }

        String message= null;
        String directory = "/root/load";
        File directoryFile = new File(directory);
        if (!directoryFile.isDirectory() && !directoryFile.exists()) {
            directoryFile.mkdirs();
        }
        //设置最终输出zip文件的目录+文件名
        String zipFileName = "已下载文件" + ".zip";
        String strZipPath = directory + "/" + zipFileName;
        File zipFile = new File(strZipPath);
        //读取需要压缩的文件
        Long fileId =null;
        String fileName=null;

        List<String> fileNames = new ArrayList<>();
        List<String> filePaths = new ArrayList<>();
        for(int i=0;i<fileIds.length;i++){
            fileId = Long.parseLong(fileIds[i]);
            if(dataFileService.queryById(fileId)!=null){
                fileName = dataFileService.queryById(fileId).getFilePath() + File.separator + dataFileService.queryById(fileId).getFileName();
                if (FileUtil.isDirectory(fileName)) {
                    List<String> stringList = FileUtil.getAllFile(fileName);
                    for (int j = 0; j < stringList.size(); j++) {
                        fileNames.add(stringList.get(j));
                        filePaths.add(dataFileService.queryById(fileId).getFilePath());
                    }
                } else {
                    fileNames.add(fileName);
                    filePaths.add(dataFileService.queryById(fileId).getFilePath());
                }
            }
        }

        ZipOutputStream zipStream = null;
        FileInputStream zipSource = null;
        BufferedInputStream bufferStream = null;
        try {
            //构造最终压缩包的输出流
            zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
            for (int i = 0; i < fileNames.size(); i++) {
                //解码获取真实路径与文件名
//                String realFilePath = java.net.URLDecoder.decode(fileNames.get(i), "UTF-8");
                String realFilePath = fileNames.get(i);
                System.out.println(realFilePath);
                File file = new File(realFilePath);
                //TODO:未对文件不存在时进行操作，后期优化。
                if (file.exists()) {
                    zipSource = new FileInputStream(file);//将需要压缩的文件格式化为输入流
                    /**
                     * 压缩条目不是具体独立的文件，而是压缩包文件列表中的列表项，称为条目，就像索引一样这里的name就是文件名,
                     * 文件名和之前的重复就会导致文件被覆盖
                     */
//                    ZipEntry zipEntry = new ZipEntry("("+i+")"+fileNames.get(i).split("/")[fileNames.get(i).split("/").length-1]);//在压缩目录中文件的名字
                    ZipEntry zipEntry = new ZipEntry(fileNames.get(i).replace(filePaths.get(i),""));//在压缩目录中文件的名字
                    zipStream.putNextEntry(zipEntry);//定位该压缩条目位置，开始写入文件到压缩包中
                    bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
                    int read = 0;
                    byte[] buf = new byte[1024 * 10];
                    while ((read = bufferStream.read(buf, 0, 1024 * 10)) != -1) {
                        zipStream.write(buf, 0, read);
                    }
                }else{
                    message=message+file.getName()+"不存在！"+"\n";
                    System.out.println(file.getName()+"不存在！");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if (null != bufferStream) bufferStream.close();
                if (null != zipStream) {
                    zipStream.flush();
                    zipStream.close();
                }
                if (null != zipSource) zipSource.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //判断系统压缩文件是否存在：true-把该压缩文件通过流输出给客户端后删除该压缩文件  false-未处理
        if (zipFile.exists()) {
            System.out.println(zipFileName);
            System.out.println(strZipPath);
            FileUtil.downloadFile(response, zipFileName, strZipPath);
            FileUtil.deleteDir(directory);
        }
        if(message==null){
            message="全部文件下载成功！";
        }
        return message;

    }


/**
 *
 *提示： 待保留代码部分
 * 作者：肖小霞

    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileIds", value = "文件id", paramType = "body", dataType = "List"),
    })
    @PostMapping("/downloadFiles")
    public ResponseResult downloadFiles(@RequestBody String fileIds) {
//        Long fileId=15L;
//        List<MultipartFile>  multipartFileList = new ArrayList<MultipartFile>();
        String clientIp = "";
        HttpServletRequest request = null;
        try {
            request =
                    ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        } catch (Exception e) {
            System.out.println("Can not get current IP.");
        }
        clientIp = request.getRemoteAddr().toString();
        System.out.println(clientIp);
        String savePath = clientIp + "/root/downLoad";
        System.out.println(savePath);
        List<String> results = new ArrayList<>();
        Long fileId = Long.parseLong(fileIds);
        String fileName = File.separator + dataFileService.queryById(fileId).getFilePath() + File.separator + dataFileService.queryById(fileId).getFileName();
        System.out.println(fileName);
        String res = FileUtil.downloadFile(fileName, savePath);
        results.add(res);


        return ResponseResult.success(results);
    }


    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileIds", value = "文件id", paramType = "body", dataType = "String"),
    })
    @RequestMapping("/downloadOneFile")
    public String downloadAlone(String fileIds, HttpServletResponse response) {
        Long fileId = Long.parseLong(fileIds);
        String fileName = File.separator + dataFileService.queryById(fileId).getFilePath() + File.separator + dataFileService.queryById(fileId).getFileName();
        File file = new File(fileName);
        System.out.println(fileName);
        if (!file.exists()) {
            System.out.println("文件 :" + File.separator + dataFileService.queryById(fileId).getFileName() + "不存在!");
        }

        response.setHeader("Content-Type","application/octet-stream");
        //设置下载的文件的名称-该方式已解决中文乱码问题
        try {
            response.setHeader("Content-Disposition","attachment;filename=" +  new String( dataFileService.queryById(fileId).getFileName().getBytes("gb2312"), "ISO8859-1" ));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        byte[] buffer = new byte[1024];
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            fis = new FileInputStream(file);
            bis = new BufferedInputStream(fis);
            OutputStream os = response.getOutputStream();
            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer, 0, i);
                i = bis.read(buffer);
            }
            System.out.println("Download  successfully!");
            return dataFileService.queryById(fileId).getFileName() + "下载成功！";

        } catch (Exception e) {
            System.out.println("Download  failed!");
            return dataFileService.queryById(fileId).getFileName() + "下载失败！";

        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }




     // 查询数据库中所有的不同年份

    @ApiOperation(value = "查询所有年份", notes = "不需要传参数")
    @PostMapping("/AllYear")
    //@RequestMapping(value="/AllYear",method = RequestMethod.POST)
    public ResponseResult distinctAllYear() {
        List<VfileMenu> vfileMenuList = vfileMenuService.distinctAllYear();
        List<Integer> yearList = new ArrayList<Integer>();
        for (int i = 0; i < vfileMenuList.size(); i++) {
            yearList.add(vfileMenuList.get(i).getFileYear());
        }
        Collections.sort(yearList);
        Collections.reverse(yearList);
        List<String> resultList = new ArrayList<String>();
        resultList.add("全部年份");
        for (int i = 0; i < yearList.size(); i++) {
            resultList.add(yearList.get(i).toString());
        }

        return ResponseResult.success(resultList);
    }


     // 查询数据库中所有的不同区域

    @ApiOperation(value = "查询所有区域", notes = "不需要传参数")
    @PostMapping("/AllRegion")
    public ResponseResult distinctAllRegion() {
        List<VfileMenu> vfileMenuList = vfileMenuService.distinctAllRegion();
        List<String> regionList = new ArrayList<String>();

        for (int i = 0; i < vfileMenuList.size(); i++) {
            regionList.add(vfileMenuList.get(i).getRegion());
        }
        Collections.sort(regionList);

        List<String> resultList = new ArrayList<String>();
        resultList.add("全部区域");
        for (int i = 0; i < regionList.size(); i++) {
            resultList.add(regionList.get(i));
        }
        return ResponseResult.success(resultList);
    }
    **/


/**
 *
 * 文件下载代码

 public String downloadMulFile2(String[] fileIds,HttpServletResponse response) {

 if(fileIds.length==1){
 Long fileId =Long.parseLong(fileIds[0]);
 String fileName= dataFileService.queryById(fileId).getFileName();
 String filePath=dataFileService.queryById(fileId).getFilePath() + File.separator + dataFileService.queryById(fileId).getFileName();
 FileUtil.downloadFile(response,fileName,filePath);
 }

 String message= null;
 String directory = "/root/load";
 File directoryFile = new File(directory);
 if (!directoryFile.isDirectory() && !directoryFile.exists()) {
 directoryFile.mkdirs();
 }
 //设置最终输出zip文件的目录+文件名
 String zipFileName = "已下载文件" + ".zip";
 String strZipPath = directory + "/" + zipFileName;
 File zipFile = new File(strZipPath);
 //读取需要压缩的文件
 Long fileId =null;
 String fileName=null;

 List<String> fileNames = new ArrayList<>();
 for(int i=0;i<fileIds.length;i++){
 fileId = Long.parseLong(fileIds[i]);
 if(dataFileService.queryById(fileId)!=null){
 fileName = dataFileService.queryById(fileId).getFilePath() + File.separator + dataFileService.queryById(fileId).getFileName();
 fileNames.add(fileName);
 }
 }

 //        System.out.println("-------------3222--------------" + fileIds);

 ZipOutputStream zipStream = null;
 FileInputStream zipSource = null;
 BufferedInputStream bufferStream = null;
 try {
 //构造最终压缩包的输出流
 zipStream = new ZipOutputStream(new FileOutputStream(zipFile));
 for (int i = 0; i < fileNames.size(); i++) {
 //解码获取真实路径与文件名
 String realFilePath = java.net.URLDecoder.decode(fileNames.get(i), "UTF-8");
 //                System.out.println(fileNames.get(i));
 System.out.println(realFilePath);
 File file = new File(realFilePath);
 //TODO:未对文件不存在时进行操作，后期优化。
 if (file.exists()) {
 zipSource = new FileInputStream(file);//将需要压缩的文件格式化为输入流

 * 压缩条目不是具体独立的文件，而是压缩包文件列表中的列表项，称为条目，就像索引一样这里的name就是文件名,
 * 文件名和之前的重复就会导致文件被覆盖

ZipEntry zipEntry = new ZipEntry("("+i+")"+fileNames.get(i).split("/")[fileNames.get(i).split("/").length-1]);//在压缩目录中文件的名字
                    zipStream.putNextEntry(zipEntry);//定位该压缩条目位置，开始写入文件到压缩包中
    bufferStream = new BufferedInputStream(zipSource, 1024 * 10);
    int read = 0;
    byte[] buf = new byte[1024 * 10];
                    while ((read = bufferStream.read(buf, 0, 1024 * 10)) != -1) {
        zipStream.write(buf, 0, read);
    }
}else{
        message=message+file.getName()+"不存在！"+"\n";
        System.out.println(file.getName()+"不存在！");
        }
        }
        } catch (Exception e) {
        e.printStackTrace();
        } finally {
        //关闭流
        try {
        if (null != bufferStream) bufferStream.close();
        if (null != zipStream) {
        zipStream.flush();
        zipStream.close();
        }
        if (null != zipSource) zipSource.close();
        } catch (IOException e) {
        e.printStackTrace();
        }
        }
        //判断系统压缩文件是否存在：true-把该压缩文件通过流输出给客户端后删除该压缩文件  false-未处理
        if (zipFile.exists()) {
        System.out.println(zipFileName);
        System.out.println(strZipPath);
        FileUtil.downloadFile(response, zipFileName, strZipPath);
        zipFile.delete();
        }
        if(message==null){
        message="全部文件下载成功！";
        }
        return message;

        }

 */

}
